#include "RomperRSA.h"

using namespace Encriptacion;

RomperRSA::RomperRSA() {
	this->rsa = new RSA();
	Configuracion* config = Configuracion::getInstancia();
	this->directorio = config->getPathAdministradores() + "romperRSA/";
	string comando = "mkdir -m 777 -p " + config->getPathAdministradores() + "romperRSA/Claves/";
	system(comando.c_str());
}

vector<unsigned long long>* RomperRSA::factorizacion(unsigned long long n) {
	vector<unsigned long long>* vec = new vector<unsigned long long> ;
	unsigned long long i;
	NumerosPrimos* arch = new NumerosPrimos();
	int pos = 0;
	if (n != 1) {
		i = arch->leerNumero(pos);
		while ((i < n + 1 && n != 1)) {
			if ((n % i) == 0) {
				vec->push_back(i);
				n = n / i;
			} else {
				pos += 7;
				i = arch->leerNumero(pos);
			}
		}
	}
	return vec;

}

ClaveRSA* RomperRSA::conseguirClavePrivada(ClaveRSA* clavePublica) {

	//Factorizamos n en 2 numeros primos
	vector<unsigned long long>* pYq = this->factorizacion(clavePublica->getModulo());

	if (pYq != NULL && pYq->size() == 2) {
		unsigned long long p = pYq->at(0);
		unsigned long long q = pYq->at(1);
		delete pYq;

		// luego se calcula fi = (p - 1) * (q - 1)
		unsigned long long fi = (p - 1) * (q - 1);

		// luego, se calcula e * d = 1 MOD (FI) utilizando el 'Algoritmo extendido de Euclides'
		// para conseguir el d de la clave PRIVADA
		unsigned long long d = rsa->algoritmoExtendidoDeEuclides(clavePublica->getPotencia(), fi);

		ClaveRSA* clavePrivada = new ClaveRSA("romperRSA", Encriptacion::Privada, d, clavePublica->getModulo());
		clavePrivada->guardarClave();
		return clavePrivada;

	} else {
		return NULL;

	}
}

string RomperRSA::desencriptarMensaje(ClaveRSA* clavePublica, string pathMenjase, string nombreAdministrador, string nombreArchivo) {

	ClaveRSA* clavePrivada = this->conseguirClavePrivada(clavePublica);

	return rsa->desencriptarArchivo(clavePrivada, pathMenjase,this->directorio + nombreAdministrador + "_RomperRSA_des" + nombreArchivo);
}

RomperRSA::~RomperRSA() {
}
